package com.xbongbong.paas.elasticsearch.model.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormSubDataEntity;
import com.xbongbong.paas.elasticsearch.constant.EsNormalConstant;
import com.xbongbong.paas.elasticsearch.model.PaasFormSubDataEsModel;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.pojo.dto.InsertDTO;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.domain.entity.UpdateDataValueEntity;
import com.xbongbong.pro.enums.errorcodes.BuinessDefaultErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.constant.StringConstant;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * 子表单处理用model(es)
 * @author 魏荣杰
 * @date 2020/9/10 19:47
 * @since
 * @version
 */
@Service("paasFormSubDataEsModel")
public class PaasFormSubDataEsModelImpl implements PaasFormSubDataEsModel {

    private static final Logger LOG = LoggerFactory.getLogger(PaasFormSubDataEsModelImpl.class);
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;


    private String type = ElasticConstant.SUB_FORM_TYPE;

    @Override
    public void insert(PaasFormSubDataEntity paasFormSubDataEntity, IndexTypeEnum indexTypeEnum) throws XbbException {
        try {
            IndexRequest indexRequest = getIndexRequest(paasFormSubDataEntity, indexTypeEnum, WriteRequest.RefreshPolicy.NONE);
            RestHighLevelClient client = xbbElasticsearchRestTemplate.getRestHighLevelClient(indexTypeEnum.getIndex());
            client.index(indexRequest, RequestOptions.DEFAULT);
        } catch (Exception e) {
            LOG.error("es插入报错",e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    @Override
    public void insert(PaasFormSubDataEntity paasFormSubDataEntity, IndexTypeEnum indexTypeEnum, WriteRequest.RefreshPolicy refreshPolicy) throws XbbException {
        try {
            IndexRequest indexRequest = getIndexRequest(paasFormSubDataEntity, indexTypeEnum, refreshPolicy);
            RestHighLevelClient client = xbbElasticsearchRestTemplate.getRestHighLevelClient(indexTypeEnum.getIndex());
            client.index(indexRequest, RequestOptions.DEFAULT);
        } catch (Exception e) {
            LOG.error("es插入报错",e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    @Override
    public void insertBatch(List<? extends PaasFormSubDataEntity> paasFormSubDataEntityList, IndexTypeEnum indexTypeEnum) throws XbbException {
        if(CollectionsUtil.isEmpty(paasFormSubDataEntityList)){
            return;
        }
        try {
            BulkRequest bulkRequest = new BulkRequest();
            for (PaasFormSubDataEntity entity : paasFormSubDataEntityList) {
                IndexRequest indexRequest = getIndexRequest(entity,indexTypeEnum , WriteRequest.RefreshPolicy.NONE);
                bulkRequest.add(indexRequest);
            }
            bulk(bulkRequest, indexTypeEnum.getIndex());
        } catch (Exception e) {
            LOG.error("es批量插入报错",e);
            throw  new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200018);
        }
    }

    @Override
    public void update(PaasFormSubDataEntity paasFormSubDataEntity, IndexTypeEnum indexTypeEnum) throws XbbException {
        try {
            //处理数据
            paasFormSubDataEntity.setEsId(indexTypeEnum.getType() + "_" + paasFormSubDataEntity.getCorpid() + "_" + paasFormSubDataEntity.getId());

            //塞入要更新的内容
            UpdateRequest updateRequest = new UpdateRequest();
            updateRequest.doc(BeanUtil.convertBean2Map(paasFormSubDataEntity,true,true))
                    .routing(paasFormSubDataEntity.getCorpid() + "_" + paasFormSubDataEntity.getDataId())
                    .index(indexTypeEnum.getIndex())
                    .id(paasFormSubDataEntity.getEsId())
            ;
            update(updateRequest, indexTypeEnum);
        } catch (Exception e) {
            LOG.error("es更新报错",e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    @Override
    public void updateBatch(List<UpdateDataEntity> list, IndexTypeEnum indexTypeEnum, WriteRequest.RefreshPolicy refreshPolicy) throws XbbException {
        try {
            if(CollectionsUtil.isEmpty(list)){
                return;
            }

            List<InsertDTO> insertList = new ArrayList<>();
            for (UpdateDataEntity updateDataEntity : list) {
                InsertDTO insertDTO = getInsertDTOForUpdateEntity(updateDataEntity, indexTypeEnum);
                insertList.add(insertDTO);
            }
            for (int i = 0; i < insertList.size(); i += EsNormalConstant.INSERT_NUM) {
                int toIndex = i + EsNormalConstant.INSERT_NUM;
                if (toIndex > insertList.size()) {
                    toIndex = insertList.size();
                }
                List<InsertDTO> newList = insertList.subList(i, toIndex);
                if (!newList.isEmpty()) {
                    BulkRequest bulkRequest = Requests.bulkRequest();
                    for (InsertDTO insertDTO : newList) {
                        insertDTO.setWaitUntil(WriteRequest.RefreshPolicy.NONE);
                        UpdateRequest updateRequest = getUpdateRequest(insertDTO, indexTypeEnum);
                        bulkRequest.add(updateRequest);
                    }
                    bulk(bulkRequest, indexTypeEnum.getIndex());
                }
            }
        } catch (Exception e) {
            LOG.error("es更新报错",e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    @Override
    public void updateBatchByEntity(List<? extends PaasFormSubDataEntity> list, IndexTypeEnum indexTypeEnum, WriteRequest.RefreshPolicy refreshPolicy) throws XbbException {
        try {
            if(CollectionsUtil.isEmpty(list)){
                return;
            }

            List<InsertDTO> insertList = new ArrayList<>();
            for (PaasFormSubDataEntity updateDataEntity : list) {
                InsertDTO insertDTO = getInsertDTOForUpdateEntity(updateDataEntity, indexTypeEnum);
                insertList.add(insertDTO);
            }
            for (int i = 0; i < insertList.size(); i += EsNormalConstant.INSERT_NUM) {
                int toIndex = i + EsNormalConstant.INSERT_NUM;
                if (toIndex > insertList.size()) {
                    toIndex = insertList.size();
                }
                List<InsertDTO> newList = insertList.subList(i, toIndex);
                if (!newList.isEmpty()) {
                    BulkRequest bulkRequest = Requests.bulkRequest();
                    for (InsertDTO insertDTO : newList) {
                        insertDTO.setWaitUntil(WriteRequest.RefreshPolicy.NONE);
                        UpdateRequest updateRequest = getUpdateRequest(insertDTO, indexTypeEnum);
                        bulkRequest.add(updateRequest);
                    }
                    bulk(bulkRequest, indexTypeEnum.getIndex());
                }
            }
        } catch (Exception e) {
            LOG.error("es更新报错",e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    private UpdateRequest getUpdateRequest(InsertDTO insertDTO, IndexTypeEnum indexTypeEnum) throws XbbException {
        UpdateRequest updateRequest = new UpdateRequest();
        Map<String, Object> source = insertDTO.getSource();
        if (Objects.isNull(source)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100077);
        }
        if (source.containsKey(BusinessConstant.ES_ID)
                && Objects.isNull(source.get(BusinessConstant.ES_ID)) && Objects.nonNull(insertDTO.getEsId())) {
            source.put(BusinessConstant.ES_ID, insertDTO.getEsId());
        }
        if (!source.containsKey(ElasticConstant.MY_JOIN_FIELD)) {
            String relations = "{\"name\":\"" + indexTypeEnum.getType() + "\",\"parent\":\"" + insertDTO.getParent()  +"\"}";
            source.put(ElasticConstant.MY_JOIN_FIELD, JSONObject.parse(relations));
        }
        updateRequest.index(insertDTO.getIndex())
                .doc(JSON.toJSONString(source, SerializerFeature.WriteMapNullValue,SerializerFeature.DisableCircularReferenceDetect),Requests.INDEX_CONTENT_TYPE)
                .id(insertDTO.getEsId())
                .routing(insertDTO.getParent())
                .setRefreshPolicy(insertDTO.getWaitUntil())
                .retryOnConflict(5)
        ;
        return updateRequest;
    }

    private InsertDTO getInsertDTOForUpdateEntity(UpdateDataEntity updateDataEntity, IndexTypeEnum indexTypeEnum) {
        InsertDTO insertDTO = new InsertDTO();
        Map<String,Object> source= new HashMap(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        JSONObject dataSource= new JSONObject();
        String route = updateDataEntity.getCorpid() + "_" + updateDataEntity.getParentId();
        List<UpdateDataValueEntity> list = updateDataEntity.getData();
        for(UpdateDataValueEntity data: list){
            String esKey = data.getEsKey();
            Object value = data.getValue();
            if(StringUtil.isEmpty(esKey)){
                continue;
            }
            if(esKey.contains("data.")){
                esKey =  esKey.replace("data.", "");
                if (CollectionsUtil.isNotEmpty(data.getSubDataList()) && esKey.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                    // 子表单更新
                    continue;
                } else {
                    dataSource.put(esKey,value);
                }
            }else {
                source.put(esKey,value);
            }
        }
        source.put("data",dataSource);
        if (Objects.nonNull(updateDataEntity.getDel())) {
            source.put("del",updateDataEntity.getDel());
        }
        if (Objects.nonNull(updateDataEntity.getUpdateTime())) {
            source.put("updateTime",updateDataEntity.getUpdateTime());
        }
        source.put("updateTime",updateDataEntity.getUpdateTime());

        String relations = "{\"name\":\"" + indexTypeEnum.getType() + "\",\"parent\":\"" + route  +"\"}";
        source.put(ElasticConstant.MY_JOIN_FIELD, JSONObject.parse(relations));
        insertDTO.setParent(route);
        insertDTO.setSource(source);
        insertDTO.setIndexTypeEnum(indexTypeEnum);
        insertDTO.setEsId(indexTypeEnum.getType() + "_" + updateDataEntity.getCorpid() + "_"+ updateDataEntity.getId());
        return insertDTO;
    }

    private InsertDTO getInsertDTOForUpdateEntity(PaasFormSubDataEntity paasFormSubDataEntity, IndexTypeEnum indexTypeEnum) {
        InsertDTO insertDTO = new InsertDTO();
        Map<String,Object> source= new HashMap(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        JSONObject dataSource= new JSONObject();
        String route = paasFormSubDataEntity.getCorpid() + "_" + paasFormSubDataEntity.getDataId();
        JSONObject data = paasFormSubDataEntity.getData();
        source.put("data",data);
        if (Objects.nonNull(paasFormSubDataEntity.getDel())) {
            source.put("del",paasFormSubDataEntity.getDel());
        }
        if (Objects.nonNull(paasFormSubDataEntity.getUpdateTime())) {
            source.put("updateTime",paasFormSubDataEntity.getUpdateTime());
        }
        source.put("updateTime",paasFormSubDataEntity.getUpdateTime());

        String relations = "{\"name\":\"" + indexTypeEnum.getType() + "\",\"parent\":\"" + route  +"\"}";
        source.put(ElasticConstant.MY_JOIN_FIELD, JSONObject.parse(relations));
        insertDTO.setParent(route);
        insertDTO.setSource(source);
        insertDTO.setIndexTypeEnum(indexTypeEnum);
        insertDTO.setEsId(indexTypeEnum.getType() + "_" + paasFormSubDataEntity.getCorpid() + "_"+ paasFormSubDataEntity.getId());
        return insertDTO;
    }

    private IndexRequest getIndexRequest(PaasFormSubDataEntity paasFormSubDataEntity, IndexTypeEnum indexTypeEnum, WriteRequest.RefreshPolicy refreshPolicy) throws XbbException {
        return getIndexRequest(paasFormSubDataEntity, indexTypeEnum.getIndex(), indexTypeEnum.getType(), refreshPolicy);
    }

    private IndexRequest getIndexRequest(PaasFormSubDataEntity paasFormSubDataEntity, String index, String type, WriteRequest.RefreshPolicy refreshPolicy) throws XbbException {
        paasFormSubDataEntity.setEsId(type + "_" + paasFormSubDataEntity.getCorpid() + "_" + paasFormSubDataEntity.getId());
        String route = paasFormSubDataEntity.getCorpid() + "_" + paasFormSubDataEntity.getDataId();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("parent", route);
        jsonObject.put("name", type);
        paasFormSubDataEntity.setMy_join_field(jsonObject);
        IndexRequest indexRequest = new IndexRequest();
        indexRequest
                .routing(route)
                .index(index)
                .setRefreshPolicy(refreshPolicy)
                .source(BeanUtil.convertBean2Map(paasFormSubDataEntity,false,true))
                .id(paasFormSubDataEntity.getEsId())
        ;
        return indexRequest;
    }

    private void update(UpdateRequest updateRequest, IndexTypeEnum indexTypeEnum) throws IOException, XbbException {
        RestHighLevelClient client = xbbElasticsearchRestTemplate.getRestHighLevelClient(indexTypeEnum.getIndex());
        updateRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.NONE).retryOnConflict(5);
        client.update(updateRequest, RequestOptions.DEFAULT);
    }

    private void bulk(BulkRequest bulkRequest,String indexName) throws XbbException {
        RestHighLevelClient client = xbbElasticsearchRestTemplate.getRestHighLevelClient(indexName);
        try {
            client.bulk(bulkRequest, RequestOptions.DEFAULT);
        } catch (Exception e) {
            LOG.error("es报错",e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }


    @Override
    public void deleteBatch(String corpid, List<? extends PaasFormSubDataEntity> entities, IndexTypeEnum indexTypeEnum, WriteRequest.RefreshPolicy refreshPolicy, DelEnum delEnum) throws XbbException {
        if (CollectionsUtil.isEmpty(entities) || StringUtil.isEmpty(corpid) || Objects.isNull(indexTypeEnum) || Objects.isNull(refreshPolicy)) {
            return;
        }
        Map<String, Object> map = new HashMap<>();
        if (Objects.isNull(delEnum)) {
            map.put(StringConstant.DEL, DelEnum.DELETE.getDel());
        } else {
            map.put(StringConstant.DEL, delEnum.getDel());
        }
        try {
            BulkRequest bulkRequest = Requests.bulkRequest();
            bulkRequest.setRefreshPolicy(refreshPolicy);
            for (PaasFormSubDataEntity entity : entities) {
                String esId = indexTypeEnum.getType() + "_" + corpid + "_" + entity.getId();
                String route = corpid + "_" + entity.getDataId();
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("parent", route);
                jsonObject.put("name", indexTypeEnum.getType());
                map.put(ElasticConstant.MY_JOIN_FIELD, jsonObject);
                UpdateRequest updateRequest = new UpdateRequest();
                updateRequest.index(indexTypeEnum.getIndex())
                        .doc(JSON.toJSONString(map, SerializerFeature.WriteMapNullValue, SerializerFeature.DisableCircularReferenceDetect), Requests.INDEX_CONTENT_TYPE)
                        .id(esId)
                        .routing(route)
                        .retryOnConflict(5);
                bulkRequest.add(updateRequest);
            }
            bulk(bulkRequest, indexTypeEnum.getIndex());
        } catch (Exception e) {
            LOG.error(BuinessDefaultErrorCodeEnum.API_ERROR_200019.getMsg(),e);
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200019);
        }
    }

    @Override
    public void deleteBatchByIdIn(String corpid, Map<Long, Long> idMap, IndexTypeEnum indexTypeEnum, WriteRequest.RefreshPolicy refreshPolicy, DelEnum delEnum) throws XbbException {
        if (idMap.isEmpty() || StringUtil.isEmpty(corpid) || Objects.isNull(indexTypeEnum) || Objects.isNull(refreshPolicy)) {
            return;
        }
        Map<String, Object> map = new HashMap<>();
        if (Objects.isNull(delEnum)) {
            map.put(StringConstant.DEL, DelEnum.DELETE.getDel());
        } else {
            map.put(StringConstant.DEL, delEnum.getDel());
        }
        try {
            BulkRequest bulkRequest = Requests.bulkRequest();
            bulkRequest.setRefreshPolicy(refreshPolicy);
            idMap.forEach((key, value)->{
                String esId = indexTypeEnum.getType() + "_" + corpid + "_" + key;
                String route = corpid + "_" + value;
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("parent", route);
                jsonObject.put("name", indexTypeEnum.getType());
                map.put(ElasticConstant.MY_JOIN_FIELD, jsonObject);
                UpdateRequest updateRequest = new UpdateRequest();
                updateRequest.index(indexTypeEnum.getIndex())
                        .doc(JSON.toJSONString(map, SerializerFeature.WriteMapNullValue, SerializerFeature.DisableCircularReferenceDetect), Requests.INDEX_CONTENT_TYPE)
                        .id(esId)
                        .routing(route)
                        .retryOnConflict(5);
                bulkRequest.add(updateRequest);
            });
            bulk(bulkRequest, indexTypeEnum.getIndex());
        } catch (Exception e) {
            LOG.error(BuinessDefaultErrorCodeEnum.API_ERROR_200019.getMsg(),e);
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200019);
        }
    }

    @Override
    public List<PaasFormSubDataEntity> getSubDataByParentId(String corpid, Integer saasMark, Integer businessType,
                                                            Long formId, Collection<Long> dataIdList, Integer page, Integer pageSize, IndexTypeEnum indexTypeEnum) throws XbbException {
        return getSubDataByParentId(corpid, saasMark, businessType, new ArrayList<>(), formId, dataIdList, 1, pageSize, DelEnum.NORMAL.getDel(), indexTypeEnum);
    }

    @Override
    public List<PaasFormSubDataEntity> getSubDataByParentIdAndDel(String corpid, Integer saasMark, Integer businessType, Long formId, Collection<Long> dataIdList, Integer page, Integer pageSize, Integer del, IndexTypeEnum indexTypeEnum) throws XbbException {
        return getSubDataByParentId(corpid, saasMark, businessType, new ArrayList<>(), formId, dataIdList, page, pageSize, del, indexTypeEnum);
    }

    @Override
    public List<PaasFormSubDataEntity> getSubDataByParentId(String corpid, Integer saasMark, Integer businessType, List<String> fieldList, Long formId, Collection<Long> dataIdList, Integer page, Integer pageSize, IndexTypeEnum indexTypeEnum) throws XbbException {
        return getSubDataByParentId(corpid, saasMark, businessType, fieldList, formId, dataIdList, page, pageSize, DelEnum.NORMAL.getDel(), indexTypeEnum);
    }

    private List<PaasFormSubDataEntity> getSubDataByParentId(String corpid, Integer saasMark, Integer businessType, List<String> fieldList, Long formId, Collection<Long> dataIdList, Integer page,
                                                             Integer pageSize, Integer del, IndexTypeEnum indexTypeEnum) throws XbbException {
        if (CollectionsUtil.isEmpty(dataIdList)) {
            return new ArrayList<>();
        }
        BoolQueryBuilder boolQueryBuilder = boolQuery();

        // 没有子表单索引的直接返回空list
        if (Objects.equals(indexTypeEnum, IndexTypeEnum.UNKNOWN)) {
            return new ArrayList<>();
        }

        boolQueryBuilder.filter(termQuery(StringConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
        if (Objects.nonNull(formId)) {
            boolQueryBuilder.filter(termQuery("formId", formId));
        }
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, del));
        boolQueryBuilder.filter(termsQuery(StringConstant.DATA_ID,  dataIdList));
        if (Objects.isNull(pageSize)) {
            pageSize = dataIdList.size() * PaasConstant.SUB_DATA_PAGE_NUM;
        }
        return getSubDataList(boolQueryBuilder, indexTypeEnum, fieldList, page, pageSize, PaasFormSubDataEntity.class);
    }

    @Override
    public <T> List<T> getSubDataList(BoolQueryBuilder boolQueryBuilder, IndexTypeEnum indexTypeEnum, List<String> fieldList, Integer page, Integer pageSize, Class<T> clazz) throws XbbException {
        // 传空数组，可以查全字段
        if (Objects.isNull(fieldList)) {
            fieldList = new ArrayList<>();
        }
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // 设置join_field
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
        List<String> subFieldList = new ArrayList<>();
        Set<String> parentFieldSet = new HashSet<>();
        fieldList.forEach(item->{
            if (item.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                if (item.contains(".")) {
                    String[] attrList = item.split("\\.");
                    if (attrList.length == 2) {
                        parentFieldSet.add(attrList[0]);
                        subFieldList.add(attrList[1]);
                    }
                } else {
                    parentFieldSet.add(item);
                }
            } else {
                subFieldList.add(item);
            }
        });
        if (CollectionsUtil.isNotEmpty(parentFieldSet)) {
            boolQueryBuilder.filter(termsQuery(StringConstant.ATTR+StringConstant.POINT+StringConstant.KEY_WORD,  parentFieldSet));
        }
        sourceBuilder.query(boolQueryBuilder);
        EsUtil.setSubFieldList(sourceBuilder, subFieldList);
        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
        searchRequest.source(sourceBuilder);
        PageRequest  pageRequest = null;
        if (Objects.nonNull(pageSize) && pageSize > EsNormalConstant.FIND_NUM) {
            // 最大限制一万条
            pageSize = EsNormalConstant.FIND_NUM;
        }
        if (Objects.nonNull(page) && Objects.nonNull(pageSize)) {
             pageRequest = EsUtil.setPage(sourceBuilder, page, pageSize);
        }
        List<T>  formDataList = xbbElasticsearchRestTemplate.queryForList(pageRequest, searchRequest,clazz);
        return formDataList;
    }

    @Override
    public <T> XbbAggregatedPage<T> list(BoolQueryBuilder boolQueryBuilder, IndexTypeEnum indexTypeEnum, List<String> fieldList, Integer page, Integer pageSize, Class<T> clazz) throws XbbException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        // 设置分页
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, page, pageSize);
        EsUtil.setFieldList(sourceBuilder, fieldList);
        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
        sourceBuilder.query(boolQueryBuilder);
        searchRequest.source(sourceBuilder);
        return xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, clazz);
    }
}
